#include <math.h>
#include <GL/glew.h>
#include <iostream>
#include <fstream>
#include <string>
#include <vector>

using namespace std;

	/*GLfloat vertices[][3] = {
	{1, 1, 1},
	{1, 1, -1},
	{1,-1,1},
	{1,-1,-1},
	{-1,1,1},
	{-1,1,-1},
	{-1,-1,1},
	{-1,-1,-1}
};

GLuint indices[][4] = {
	{0,1,3,2},
	{4,5,7,6},

	{0,2,6,4},
	{1,3,7,5}, 
	
	{0,1,5,4},
	{2,3,7,6}
};

GLfloat colors[][3] = {
	{1,0,0},
	{1,0,0},
	{1,0,0},
	{1,0,0},
	{1,0,0},
	{1,0,0},
	{1,0,0},
	{1,0,0}
};*/
class myObject3D
{
public:
	GLuint buffers[4];

	GLfloat **vertices;
	GLfloat **colors;
	GLuint **indices;
	GLfloat *normals;

	int nbVertices, nbIndices;
  
	myObject3D() {
	}

	void split(vector<string> &tokens, const string &text, char sep) 
	{
		int start = 0, end = 0;
		tokens.clear();
		while ((end = text.find(sep, start)) != string::npos) {
			tokens.push_back(text.substr(start, end - start));
			start = end + 1;
		}
		tokens.push_back(text.substr(start));
	}

	void readMesh(char *filename)
	{
		ifstream file(filename);
		vector<string> tokens;
		string ligne;
		nbVertices = 0;
		nbIndices = 0;

		if(file)
		{
			if ( getline(file, ligne) )
			{
				split(tokens,ligne,' ');

				vertices =  new GLfloat*[atoi(tokens[0].c_str())]; //(GLfloat*)malloc(atoi(tokens[0].c_str()) * sizeof(GLfloat*));
				indices =  new GLuint*[atoi(tokens[1].c_str())]; //(GLuint*)malloc(atoi(tokens[1].c_str()) * sizeof(GLuint*));
				colors = new GLfloat*[atoi(tokens[0].c_str())];
				

				while(getline(file, ligne)) 
				{
					split(tokens,ligne,' ');

					if (tokens[0] == "v")
                    {
						vertices[nbVertices] = new GLfloat[3];
                        vertices[nbVertices][0] = atof(tokens[1].c_str());
                        vertices[nbVertices][1] = atof(tokens[2].c_str());
                        vertices[nbVertices][2] = atof(tokens[3].c_str());

						colors[nbVertices] = new GLfloat[3];
						colors[nbVertices][0] = 1;
						colors[nbVertices][1] = 0;
						colors[nbVertices][2] = 0;

                        nbVertices++;
                    }
                    else if (tokens[0] == "f")
                    {
						indices[nbIndices] = new GLuint[4];
                        indices[nbIndices][0] = atoi(tokens[1].c_str()) - 1;
                        indices[nbIndices][1] = atoi(tokens[2].c_str()) - 1;
                        indices[nbIndices][2] = atoi(tokens[3].c_str()) - 1;
						indices[nbIndices][3] = atoi(tokens[4].c_str()) - 1;
                        nbIndices++;
					}
				}
				cout << "nbVertices : " << nbVertices << endl;
				cout << "nbIndices : " << nbIndices << endl;

				cout << vertices[0][0]  << " " << vertices[0][1] << " " << vertices[0][2] << endl;
				cout << indices[0][0]  << " " << indices[0][1] << " " << indices[0][2] << " " << indices[0][3] << endl;
			}
			else
			{
				cout << "File empty" << endl;
			}
		}
		else
		{
			cout << "Cant open file" << endl;
		}
	}

	void computeNormals( )
	{
		/**ADD CODE**/
	}

	void createObjectBuffers()
	{
		/*glGenBuffers(3, buffers);
	
		glBindBuffer(GL_ARRAY_BUFFER, buffers[0]);
		glBufferData(GL_ARRAY_BUFFER, nbVertices*3*4, vertices, GL_STATIC_DRAW);

		glBindBuffer(GL_ARRAY_BUFFER, buffers[1]) ; 
		glBufferData(GL_ARRAY_BUFFER, nbVertices*3*4, colors, GL_STATIC_DRAW);
 
		glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffers[2]);
		glBufferData(GL_ELEMENT_ARRAY_BUFFER, nbIndices*3*4, indices, GL_STATIC_DRAW);*/
		glGenBuffers(3, buffers);
	
	glBindBuffer(GL_ARRAY_BUFFER, buffers[0]);
    glBufferData(GL_ARRAY_BUFFER, 8*3*4, vertices, GL_STATIC_DRAW);

	glBindBuffer(GL_ARRAY_BUFFER, buffers[1]) ; 
    glBufferData(GL_ARRAY_BUFFER, 8*3*4, colors, GL_STATIC_DRAW);
 
	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffers[2]);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, 6*4*4, indices, GL_STATIC_DRAW);
	}

	void displayObject()
	{
		/*glBindBuffer(GL_ARRAY_BUFFER, buffers[0]);
		glVertexPointer(3, GL_FLOAT, 0, 0);
		glEnableClientState(GL_VERTEX_ARRAY);

		glBindBuffer(GL_ARRAY_BUFFER, buffers[1]);
		glColorPointer(3, GL_FLOAT, 0, 0) ; 
		glEnableClientState(GL_COLOR_ARRAY) ; 

		glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffers[2]);

		glDrawElements(GL_QUADS, nbIndices*4, GL_UNSIGNED_INT, 0) ; */
			glBindBuffer(GL_ARRAY_BUFFER, buffers[0]);
    glVertexPointer(3, GL_FLOAT, 0, 0);
    glEnableClientState(GL_VERTEX_ARRAY);

    glBindBuffer(GL_ARRAY_BUFFER, buffers[1]);
    glColorPointer(3, GL_FLOAT, 0, 0) ; 
    glEnableClientState(GL_COLOR_ARRAY) ; 

    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffers[2]);

    glDrawElements(GL_QUADS, 6*4, GL_UNSIGNED_INT, 0) ;
	}

	void displayNormals()
	{
		/**ADD CODE**/
	}
};
